﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.ServiceModel.DomainServices.Client;
using System.Windows.Controls;
using System.Windows.Data;
using GSSoftSL.Models;
using GSSoftSL.Utility;
using GSSoftSL.Web.Models;
using GSSoftSL.Web.Services;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using Microsoft.Windows.Data.DomainServices;

namespace GSSoftSL.ViewModel
{
    /// <summary>
    /// This class contains properties that a View can data bind to.
    /// <para>
    /// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
    /// </para>
    /// <para>
    /// See http://www.galasoft.ch/mvvm/getstarted
    /// </para>
    /// </summary>
    public class LopViewModel : ViewModelBase
    {
        private bool _isBusy = false;
        public bool IsBusy
        {
            get { return _isBusy; }
            set
            {
                _isBusy = value;
                RaisePropertyChanged("IsBusy");
            }
        }

        private Mon[] _mons;
        public Mon[] Mons
        {
            get { return _mons; }
            set 
            { 
                _mons = value;
                RaisePropertyChanged("Mons");
            }
        }

        private Mon _currentMon;
        public Mon CurrentMon
        {
            get { return _currentMon; }
            set
            {
                if (_currentMon == value)// || _gvs == null)
                    return;
                _currentMon = value;
                RaisePropertyChanged("CurrentMon");
            }
        }

        public Phong[] Phongs { get; set; }

        private GSSoftContext _dc;

        /// <summary>
        /// Initializes a new instance of the GiaoVienViewModel class.
        /// </summary>
        public LopViewModel()
        {
            Init();
        }

        private bool _isLoadingLop = false;
        private bool _isLoadingPhong = false;
        private bool _isLoadingMon = false;
        //private bool _isLoadingGiaoVien = false;
        private void Init()
        {
            _dc = _dc = new GSSoftContext();//(GSSoftContext)context;
            IsBusy = _isLoadingLop = _isLoadingPhong = _isLoadingMon = true;
            //_dc.Load<Lop>(_dc.GetLopsWithGiaoViens_MonsQuery().OrderBy(n => n.MaMon).ThenBy(n => n.TrangThai).ThenBy(n => n.MaLop), LoadBehavior.RefreshCurrent, LoadLop_Completed, null);
            _dc.Load<Lop>(_dc.GetLopsQuery().OrderBy(n => n.MaMon).ThenBy(n => n.TrangThai).ThenBy(n => n.MaLop), LoadBehavior.RefreshCurrent, LoadLop_Completed, null);
            _dc.Load<Phong>(_dc.GetPhongsQuery().OrderBy(n => n.Tang), LoadBehavior.RefreshCurrent, LoadPhong_Completed, null);
            //_dc.Load<Mon>(_dc.GetMonsWithGiaoVienMonsQuery().OrderBy(n => n.ThuTu), LoadBehavior.RefreshCurrent, LoadMonCompleted, null);
            _dc.Load<Mon>(_dc.GetMonsQuery().OrderBy(n => n.ThuTu), LoadBehavior.RefreshCurrent, LoadMonCompleted, null);
        }

        private void LoadPhong_Completed(LoadOperation<Phong> loadPhong)
        {
            Phongs = loadPhong.Entities.ToArray();
            _isLoadingPhong = false;
            IsBusy = _isLoadingLop & _isLoadingPhong & _isLoadingMon;
        }

        private void LoadLop_Completed(LoadOperation<Lop> loadLop)
        {
            
            Lops = new PagedCollectionView(new EntityList<Lop>(_dc.Lops, loadLop.Entities));
            _isLoadingLop = false;
            IsBusy = _isLoadingLop & _isLoadingPhong & _isLoadingMon;
        }

        private void LoadMonCompleted(LoadOperation<Mon> obj)
        {
            Mons = obj.Entities.ToArray();
            _isLoadingMon = false;
            IsBusy = _isLoadingLop & _isLoadingPhong & _isLoadingMon;
        }

        public PagedCollectionView _lops;
        public PagedCollectionView Lops
        {
            get { return _lops; }
            set
            {
                _lops = value;
                _lops.CurrentChanged += (s, e) =>
                                            {
                                                if (_lops.CurrentItem != null)
                                                {
                                                    Current = _lops.CurrentItem as Lop;
                                                    if (Current!= null && Current.MaLop == null)
                                                        Current.MaLop = "";
                                                }
                                            };
                RaisePropertyChanged("Lops");
            }
        }

        private Lop _current;
        public Lop Current
        {
            get { return _current; } 
            set 
            {
                
                if (_current == value)
                    return;
                if (value != null && value.EntityState == EntityState.Modified)
                    _dc.RejectChanges();
                if (_current != null && _current.EntityState == EntityState.Modified)
                    _dc.RejectChanges();
                _current = value;
                if (_current != null && _current.MaLop == null)
                {
                    _current.MaLop = "";
                    _current.LopId = Guid.NewGuid();
                }
                
                RaisePropertyChanged("Current");
            }
        }

        private RelayCommand<DataFormEditEndedEventArgs> _saveCommand;
        /// <summary>
        /// Gets the SaveCommand.
        /// </summary>
        public RelayCommand<DataFormEditEndedEventArgs> SaveCommand
        {
            get
            {
                return _saveCommand
                       ?? (_saveCommand = new RelayCommand<DataFormEditEndedEventArgs>(
                                              (arg) =>
                                                  {
                                                      if (((Current == null || !_dc.HasChanges || _dc.IsSubmitting)) && arg.EditAction == DataFormEditAction.Commit)
                                                          return;
                                                      ConfirmWindow.CreateNew("Bạn có muốn lưu?", Save);
                                                  },
                                              (arg) =>
                                              (!(Current == null || !_dc.HasChanges || _dc.IsSubmitting)) &&
                                              arg.EditAction == DataFormEditAction.Commit));
            }
        }

        private void Save()
        {
            if (Current.EntityState == EntityState.New)
            {
                IsBusy = true;
                Current.NgayTao = Current.NgayCapNhat = DateTime.Now;
                Current.NguoiTao =
                    Current.NguoiCapNhat = UtilityFunction.GetCurrentUserId();
            }
            else if (Current.EntityState == EntityState.Modified)
            {
                Current.NgayCapNhat = DateTime.Now;
                Current.NguoiCapNhat = UtilityFunction.GetCurrentUserId();
            }
            IsBusy = true;
            _dc.SubmitChanges(SubmitChangesEnd, null);
        }

        public RelayCommand FilterGiaoVienCommand;

        public void FilterGiaoVien(string MaMon)
        {
            //this.CurrentMon = MaMon;
        }

        private void SubmitChangesEnd(SubmitOperation e)
        {
            if (e.HasError)
            {
                DomainOperationException error = e.Error as DomainOperationException;
                if (error != null && error.Status == OperationErrorStatus.ServerError)
                {
                    if (Current.EntityState == EntityState.New)
                    {
                        foreach (Lop lop in e.ChangeSet)
                        {
                            if (lop == null)
                                continue;
                            if (lop != Current)
                                lop.EntityConflict.Resolve();
                        }
                    }
                }
            }
            IsBusy = false;
        }

        private RelayCommand _refreshCommand;
        public RelayCommand RefreshCommand
        {
            get
            {
                return _refreshCommand
                    ?? (_refreshCommand = new RelayCommand(Init));
            }
        }
    }

}